ACM/ICPC 之 并查集-食物链(POJ1182)

  并查集的经典题型,POJ上题目还是中文= =,一般看到中文题都会感觉不太简单,这道题的数学归纳用得比较多,可以简化代码,挺有意思的。

  同类型的题目还有POJ1703,比这个要简单,想了解并查集基本介绍或想参考Code请移步:算法手记 之 数据结构(并查集详解)(POJ1703)

  


 

 

  存在食物链: A吃B,B吃C,C吃A

  给出两种判断:1 a b  指a和b相同

         2 a b  指a吃b

  现依照题目输入,输出判断的错误次数:1.a,b超过N错误

                    2.a,b不符合前面判断则错误

  Code仅供参考:

  

 1 //食物链:A吃B,B吃C,C吃A
 2 //r[]中:0为同类,1为父亲吃自己,2为自己吃父亲
 3 //Time:204Ms    Memory:556K
 4 #include<iostream>
 5 #include<cstring>
 6 #include<cstdio>
 7 using namespace std;
 8 #define MAX 50005
 9 int n, k;
10 int fa[MAX], r[MAX];    //father node - ralation
11 int fake;    //假话总数
12 int find(int x)
13 {
14     if (x != fa[x])
15     {
16         int tmp = fa[x];
17         fa[x] = find(fa[x]);    //压缩路径
18         r[x] = (r[x] + r[tmp]) % 3;    //归纳得出
19     }
20     return fa[x];
21 }
22 int main()
23 {
24     scanf("%d%d", &n, &k);
25     
26     for (int i = 1; i <= n; i++)
27         fa[i] = i;    //将父结点设为自己
28     for (int i = 0; i < k; i++)
29     {
30         int flag, a, b;
31         scanf("%d%d%d", &flag, &a, &b);
32         if (a > n || b > n)
33         {
34             fake++;    
35             continue;
36         }
37         int pa = find(a), pb = find(b);
38         if (flag == 1)
39         {
40             if (pa != pb)
41             {
42                 fa[pa] = pb;
43                 r[pa] = (r[b] - r[a] + 3) % 3;    //归纳得出
44             }
45             else if (r[a] != r[b])
46                 fake++;
47         }
48         else {
49             if (pa != pb) {
50                 fa[pa] = pb;
51                 r[pa] = (r[b] - r[a] + 3) % 3 + 1;    //归纳得出
52             }
53             else if ((r[a] - r[b] + 3) % 3 != 1)    //归纳得出
54                 fake++;
55         }
56     }
57     printf("%d\n", fake);
58     return 0;
59 }

 

posted @ 2016-03-14 23:40  文字失效  阅读(460)  评论(0编辑  收藏  举报